package java学习.代码随想录.动态规划;

/**
 * **************
 * 项目名称: 蓝桥杯-Java学习 <br/>
 * 文件名称:  <br/>
 * 文件描述: 这里添加您的类文件描述，说明当前文件要包含的功能。 <br/>
 * 文件创建：刘世锦Lenovo <br/>
 * 创建时间: 2022/8/5 <br/>
 *
 * @version v1.0 <br/>
 * @update [序号][日期YYYY-MM-DD][更改人姓名][变更描述]<br/>
 * *************
 */
public class 不同路径II {
    public static void main(String[] args) {

        /**
         * 一个机器人位于一个 m x n 网格的左上角 （起始点在下图中标记为“Start” ）。
         *
         * 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角（在下图中标记为“Finish”）。
         *
         * 现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径？
         * 网格中的障碍物和空位置分别用 1 和 0 来表示。
         *
         * 示例 1：
         * 输入：obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
         * 输出：2 解释：
         * 3x3 网格的正中间有一个障碍物。
         * 从左上角到右下角一共有 2 条不同的路径：
         * 向右 -> 向右 -> 向下 -> 向下
         * 向下 -> 向下 -> 向右 -> 向右
         */



    }
//    行：row. 列：column.
    public static int  func (int[][] obstacleGrid ){
        int   row = obstacleGrid.length;
        int column = obstacleGrid[0].length;
        if (row==0){
            return 1;
        }
        int[][] dp = new int[row][column];
        // 初始化 dp 有障碍物的路径数都是0；其余是1
        for (int i = 0; i < dp.length; i++) {
            if (obstacleGrid[i][0]==0 ){
                dp[i][0] = 1;
            }else{
                dp[i][0] = 0;
            }
        }
        for (int i = 0; i < dp.length; i++) {
            if (obstacleGrid[0][i]==0 ){
                // 无障碍的是路径数是1
                dp[0][i] = 1;
            }else{
//                其余情况都是有障碍物，都得是0： obstacleGrid[0][i]==1 || dp[0][i-1] == 0 (前一个的可达路径数就是0了)
                dp[i][0] = 0;
            }

        }
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < column; j++) {

                if (obstacleGrid[i][j] ==0){
//                    只有在无障碍物时才能计算
                    dp[i][j] = dp[i-1][j]+dp[i][j-1];
                }

            }
        }

        return dp[row-1][column-1];
    }

    //    write on leetcode by me
    public int uniquePathsWithObstacles1(int[][] obstacleGrid) {
        int   row = obstacleGrid.length;
        int column = obstacleGrid[0].length;
        if (row==0||obstacleGrid==null){
            return 0;
        }
        int[][] dp = new int[row][column];
        int m = obstacleGrid.length, n = obstacleGrid[0].length;
//         // 初始化 dp 不是障碍物的路径数都是1；其余是0
//         for (int i = 0; i < row && obstacleGrid[i][0]==0; i++) {
//             // if (obstacleGrid[i][0]==0){
//                 dp[i][0] = 1;
//             // }
//         }
//         for (int i = 0; i < column && obstacleGrid[0][i]==0; i++) {
//             // if (obstacleGrid[0][i]==0){
//                 dp[0][i] = 1;
//             // }
//         }
        for (int i = 0; i < dp.length; i++) {
            if (obstacleGrid[i][0]==0 ){
                dp[i][0] = 1;
            }else{dp[i][0] = 0;}
        }
        for (int i = 0; i < dp.length; i++) {
            if (obstacleGrid[0][i]==0 ){
                dp[0][i] = 1;
            }else{dp[i][0] = 0;}

        }
        //  for(int i = 1; i < n; ++i) {
        //     if(obstacleGrid[i][0] == 1 || dp[i - 1][0] == 0) {
        //         dp[i][0] = 0;
        //     } else {
        //         dp[i][0] = 1;
        //     }
        // }
        // //处理第一行
        // for(int j = 1; j < m; ++j) {
        //     if(obstacleGrid[0][j] == 1 || dp[0][j - 1] == 0) {
        //         dp[0][j] = 0;
        //     } else {
        //         dp[0][j] = 1;
        //     }
        // }

        for (int i = 1; i < row; i++) {
            for (int j = 1; j < column; j++) {
                if (obstacleGrid[i][j] ==0){
//                    只有在无障碍物时才能计算
                    dp[i][j] = dp[i-1][j]+dp[i][j-1];
                }

            }
        }

        return dp[row-1][column-1];
    }

//    write on leetcode by answer
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        if (obstacleGrid == null || obstacleGrid.length == 0) {
            return 0;
        }

        // 定义 dp 数组并初始化第 1 行和第 1 列。
        int m = obstacleGrid.length, n = obstacleGrid[0].length;
        int[][] dp = new int[m][n];
        for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) {
            dp[i][0] = 1;
        }
        for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) {
            dp[0][j] = 1;
        }

        // 根据状态转移方程 dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 进行递推。
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (obstacleGrid[i][j] == 0) {
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
                }
            }
        }
        return dp[m - 1][n - 1];
    }
}
